package cn.yunbamboos.rest.service.apidoc.helper;

import cn.yunbamboos.rest.service.anno.param.ParamType;
import cn.yunbamboos.rest.service.apidoc.meta.MediaType;
import cn.yunbamboos.rest.service.apidoc.meta.Schema;
import cn.yunbamboos.rest.service.apidoc.meta.schema.DefaultSchema;
import cn.yunbamboos.rest.service.apidoc.meta.schema.ObjectSchema;
import cn.yunbamboos.rest.service.dto.DTO;
import cn.yunbamboos.rest.service.dto.out.PageOutDTO;
import com.alibaba.fastjson2.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.List;

public class ReadResponseHelper extends ReadObjectHelper{

    private static final Logger logger = LoggerFactory.getLogger(ReadResponseHelper.class);

    private final Class<? extends DTO> out;

    private final MediaType mediaType = new MediaType();

    public ReadResponseHelper(Class<? extends DTO> out){
        this.out = out;
    }

    public void read() {
        ObjectSchema schema = new ObjectSchema("object");
        addProperty(schema, "integer", "code", "返回编码", "200");
        addProperty(schema, "string", "msg", "返回描述", "OK");
        // 读取所有属性
        logger.info("读取OutDTO: {}", out);
        readDataSchema(schema, out);

        mediaType.setSchema(schema);
        // 响应示例
        JSONObject examples = new JSONObject();
        schema.toExample(examples);

        JSONObject ok = new JSONObject();
        ok.put("summary", "成功示例");
        ok.put("value", examples.getJSONObject("object"));

        mediaType.putExamples("1", ok);
    }

    public MediaType getMediaType() {
        return mediaType;
    }

    public Schema getModel(ParamType paramType, Field field){
        Class<?> parentClass = out.getSuperclass();
        if(PageOutDTO.class.isAssignableFrom(parentClass)){
            Class<?> modelClass = this.getGeneric(out);
            ObjectSchema schema = new ObjectSchema("object");
            readObject(schema, modelClass);
            return schema;
        }
        return null;
    }

    private void readDataSchema(Schema schema, Class<?> obj) {
        List<Field> fields = this.getDeclaredFields(obj);
        if(!fields.isEmpty()){
            ObjectSchema dateSchema = new ObjectSchema("data");
            schema.addProperty("data", dateSchema);
            schema.addRequired("data");
            this.readObject(dateSchema, obj);
        }
    }

    private static void addProperty(Schema schema, String type, String name, String title,String example) {
        DefaultSchema defaultSchema = new DefaultSchema(name, type);
        defaultSchema.setTitle(title);
        defaultSchema.setExample(example);
        schema.addProperty(name, defaultSchema);
        schema.addRequired(name);
    }

}
